﻿namespace Microsoft.VisualStudio.TextTemplating.CommandLine
{
    using System;
    using System.Collections;
    using System.Globalization;
    using System.Reflection;

    internal class OptionSpecificationCollection : CollectionBase
    {
        public void Add(OptionSpecification specification)
        {
            if (this.Contains(specification.OptionName))
            {
                throw new OptionSpecificationException(string.Format(CultureInfo.CurrentCulture, "Option {0} is specified twice", new object[] { specification.OptionName }));
            }
            base.InnerList.Add(specification);
        }

        public bool Contains(string optionName)
        {
            foreach (OptionSpecification specification in base.InnerList)
            {
                if (string.Compare(specification.OptionName, optionName, true, CultureInfo.CurrentCulture) == 0)
                {
                    return true;
                }
            }
            return false;
        }

        public OptionSpecification[] GetPartial(string partialOptionName)
        {
            ArrayList list = new ArrayList();
            foreach (OptionSpecification specification in base.InnerList)
            {
                if (string.Compare(partialOptionName, 0, specification.OptionName, 0, partialOptionName.Length, true, CultureInfo.CurrentCulture) == 0)
                {
                    list.Add(specification);
                }
            }           
            return (OptionSpecification[]) list.ToArray(typeof(OptionSpecification));
        }

        public void LoadFromType(Type t)
        {
            foreach (OptionAttribute attribute in t.GetCustomAttributes(typeof(OptionAttribute), true))
            {
                OptionSpecification specification = new OptionSpecification(attribute, null);
                this.Add(specification);
            }
            foreach (PropertyInfo info in t.GetProperties(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance))
            {
                object[] customAttributes = info.GetCustomAttributes(typeof(OptionAttribute), true);
                if (customAttributes.Length == 1)
                {
                    if ((info.GetSetMethod(true) == null) && !typeof(IList).IsAssignableFrom(info.PropertyType))
                    {
                        throw new OptionSpecificationException(string.Format(CultureInfo.CurrentCulture, "The property '{0}' has no setter so it cannot be used as an option.", new object[] { info.Name }));
                    }
                    OptionAttribute attribute2 = customAttributes[0] as OptionAttribute;
                    OptionSpecification specification2 = new OptionSpecification(attribute2, info);
                    this.Add(specification2);
                }
                else if (customAttributes.Length != 0)
                {
                    throw new OptionSpecificationException(string.Format(CultureInfo.CurrentCulture, "The property '{0}' has been marked with two or more options", new object[] { info.Name }));
                }
            }
        }
    }
}

